<script lang="ts">
	import { createEventDispatcher, getContext } from 'svelte'
	import type { FlowEditorContext } from '../flows/types'
	import { emptyFlowModuleState } from '../flows/utils'
	import { clickButtonBySelector, updateFlowModuleById, triggerPointerDown } from './utils'
	import Tutorial from './Tutorial.svelte'
	import { updateProgress } from '$lib/tutorialUtils'
	import { nextId } from '../flows/flowModuleNextId'

	const dispatch = createEventDispatcher()
	const { flowStore, selectedId, flowStateStore } =
		getContext<FlowEditorContext>('FlowEditorContext')

	let tutorial: Tutorial | undefined = undefined

	export function runTutorial(indexToInsertAt?: number | undefined) {
		tutorial?.runTutorial({ indexToInsertAt })
	}
</script>

<Tutorial
	bind:this={tutorial}
	index={1}
	name="forloop"
	tainted={false}
	on:error
	on:skipAll
	getSteps={(driver, options) => {
		const id = nextId($flowStateStore, $flowStore)
		const index = options?.indexToInsertAt ?? $flowStore.value.modules.length

		let tempId = ''

		return [
			{
				popover: {
					title: 'For loops tutorial',
					description:
						'Learn how to build our first for loop to iterate on. You can use arrow keys to navigate.'
				}
			},

			{
				element: `#flow-editor-add-step-${index}`,
				popover: {
					title: 'Add a step',
					description: 'Click here to add a step to your flow',
					onNextClick: () => {
						triggerPointerDown(`#flow-editor-add-step-${index}`)

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},

			{
				popover: {
					title: 'Steps kind',
					description: "Choose the kind of step you want to add. Let's start with a simple action"
				},
				element: '#flow-editor-insert-module'
			},

			{
				popover: {
					title: 'Insert a loop',
					description: "Let's pick a for loop",
					onNextClick: () => {
						triggerPointerDown('#flow-editor-flow-kind-for-loop')
						setTimeout(() => {
							driver.moveNext()
						})
					}
				},
				element: '#flow-editor-flow-kind-for-loop'
			},

			{
				element: '#flow-editor-iterator-expression',
				popover: {
					title: 'Iterator expression',
					description:
						'The iterator expression is a JavaScript expression that respresents the array to iterate on. Here we will iterate on the firstname input letter by letter',
					onNextClick: () => {
						updateFlowModuleById($flowStore, id, (module) => {
							if (module.value.type === 'forloopflow') {
								if (module.value.iterator.type === 'javascript') {
									module.value.iterator.expr = '[1,2,3]'
								}
							}
						})

						dispatch('reload')

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},

			{
				element: '#flow-editor-iterator-expression',
				popover: {
					title: 'Iterator expression',
					description:
						'We can refer to the result of previous steps using the results object: results.a or use static values like [1,2,3] in this case.',
					onNextClick: () => {
						updateFlowModuleById($flowStore, id, (module) => {
							const newId = nextId($flowStateStore, $flowStore)
							tempId = newId

							if (module.value.type === 'forloopflow') {
								module.value.modules = [
									{
										id: newId,
										value: {
											type: 'rawscript',
											content: 'def main(x):\n    return x',
											// @ts-ignore
											language: 'python3',
											input_transforms: {
												x: {
													type: 'javascript',
													// @ts-ignore
													value: '',
													expr: ''
												}
											}
										}
									}
								]
							}

							$flowStateStore[newId] = emptyFlowModuleState()
							let schema = $flowStateStore[newId].schema ?? { properties: {} }
							schema.properties = {
								x: {
									type: 'string',
									description: '',
									default: null
								}
							}
						})

						dispatch('reload')

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},
			{
				popover: {
					title: 'Step of the loop',
					description: 'We added an action to the loop. Let’s configure it',
					onNextClick: () => {
						$selectedId = tempId
						$flowStore = $flowStore

						dispatch('reload')
						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},
			{
				element: '#flow-editor-editor',
				popover: {
					title: 'Python step',
					description:
						'We can write python code in the editor. In this example we will capitalize the letter'
				}
			},

			{
				element: '#flow-editor-step-input',
				popover: {
					title: 'Flow inputs',
					description: 'UI is autogenerated from your code.'
				}
			},
			{
				element: '#flow-editor-plug',
				popover: {
					title: 'Input configuration',
					description: 'Let’s connect the input to the letter input',
					onNextClick: () => {
						clickButtonBySelector('#flow-editor-plug')

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},
			{
				element: '.key',
				popover: {
					title: 'Connect',
					description: 'As we did before, we can connect to the iterator of the loop',
					onNextClick: () => {
						updateFlowModuleById($flowStore, id, (module) => {
							if (
								module.value.type === 'forloopflow' &&
								module.value.modules[0].value.type === 'rawscript'
							) {
								module.value.modules[0].value.input_transforms = {
									x: {
										type: 'javascript',
										expr: 'flow_input.iter.value'
									}
								}
							}
						})

						dispatch('reload')

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},
			{
				element: '#flow-editor-step-input',
				popover: {
					title: 'Iterator',
					description:
						'Loops expose an iterator object that contains the current value of the loop and the index',
					onNextClick: () => {
						setTimeout(() => {
							driver.moveNext()

							updateProgress(1)
						})
					}
				}
			},
			{
				element: '#flow-editor-test-flow',
				popover: {
					title: 'Test your flow',
					description: 'We can now test our flow',
					onNextClick: () => {
						clickButtonBySelector('#flow-editor-test-flow')

						setTimeout(() => {
							driver.moveNext()
						})
					}
				}
			},

			{
				element: '#flow-editor-test-flow-drawer',
				popover: {
					title: 'Test your flow',
					description: 'Finally we can test our flow, and view the results!',
					onNextClick: () => {
						clickButtonBySelector('#flow-editor-test-flow-drawer')

						setTimeout(() => {
							driver.moveNext()

							updateProgress(0)
						})
					}
				}
			}
		]
	}}
/>
